<!DOCTYPE html>
<html lang="en-US">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>架构设计 | Elastic Crontab System</title>
    <meta name="description" content="一款简单易用的分布式定时任务管理系统">
    
    
    <link rel="preload" href="/ects/assets/css/0.styles.4b878e04.css" as="style"><link rel="preload" href="/ects/assets/js/app.dc03944a.js" as="script"><link rel="preload" href="/ects/assets/js/6.fe2e5ce2.js" as="script"><link rel="prefetch" href="/ects/assets/js/10.a9b3e2ed.js"><link rel="prefetch" href="/ects/assets/js/11.8d62d449.js"><link rel="prefetch" href="/ects/assets/js/12.f9d3cea2.js"><link rel="prefetch" href="/ects/assets/js/13.de2731d4.js"><link rel="prefetch" href="/ects/assets/js/2.f8f0e8d9.js"><link rel="prefetch" href="/ects/assets/js/3.5a2a6f56.js"><link rel="prefetch" href="/ects/assets/js/4.fc5cf636.js"><link rel="prefetch" href="/ects/assets/js/5.3002656a.js"><link rel="prefetch" href="/ects/assets/js/7.fbbe362c.js"><link rel="prefetch" href="/ects/assets/js/8.50df79d7.js"><link rel="prefetch" href="/ects/assets/js/9.4a0eec1b.js">
    <link rel="stylesheet" href="/ects/assets/css/0.styles.4b878e04.css">
  </head>
  <body>
    <div id="app" data-server-rendered="true"><div class="theme-container"><header class="navbar"><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div> <a href="/ects/" class="home-link router-link-active"><!----> <span class="site-name">Elastic Crontab System</span></a> <div class="links" style="max-width:nullpx;"><div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""> <!----></div> <nav class="nav-links can-hide"><div class="nav-item"><a href="/ects/introduction/architecture.html" class="nav-link router-link-exact-active router-link-active">项目介绍</a></div><div class="nav-item"><a href="/ects/developer/" class="nav-link">开发文档</a></div><div class="nav-item"><a href="https://github.com/betterde/ects/releases" target="_blank" rel="noopener noreferrer" class="nav-link external">
  下载
  <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></div><div class="nav-item"><a href="https://github.com/betterde/ects" target="_blank" rel="noopener noreferrer" class="nav-link external">
  Github
  <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></div> <!----></nav></div></header> <div class="sidebar-mask"></div> <div class="sidebar"><nav class="nav-links"><div class="nav-item"><a href="/ects/introduction/architecture.html" class="nav-link router-link-exact-active router-link-active">项目介绍</a></div><div class="nav-item"><a href="/ects/developer/" class="nav-link">开发文档</a></div><div class="nav-item"><a href="https://github.com/betterde/ects/releases" target="_blank" rel="noopener noreferrer" class="nav-link external">
  下载
  <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></div><div class="nav-item"><a href="https://github.com/betterde/ects" target="_blank" rel="noopener noreferrer" class="nav-link external">
  Github
  <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></div> <!----></nav>  <ul class="sidebar-links"><li><a href="/ects/introduction/architecture.html" class="active sidebar-link">架构设计</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/ects/introduction/architecture.html#主节点" class="sidebar-link">主节点</a></li><li class="sidebar-sub-header"><a href="/ects/introduction/architecture.html#从节点" class="sidebar-link">从节点</a></li><li class="sidebar-sub-header"><a href="/ects/introduction/architecture.html#服务注册" class="sidebar-link">服务注册</a></li><li class="sidebar-sub-header"><a href="/ects/introduction/architecture.html#服务发现" class="sidebar-link">服务发现</a></li><li class="sidebar-sub-header"><a href="/ects/introduction/architecture.html#流水线" class="sidebar-link">流水线</a></li><li class="sidebar-sub-header"><a href="/ects/introduction/architecture.html#任务" class="sidebar-link">任务</a></li><li class="sidebar-sub-header"><a href="/ects/introduction/architecture.html#关联关系" class="sidebar-link">关联关系</a></li></ul></li><li><a href="/ects/introduction/dependencies.html" class="sidebar-link">环境依赖</a></li><li><a href="/ects/introduction/configuration.html" class="sidebar-link">服务配置</a></li><li><a href="/ects/introduction/services.html" class="sidebar-link">运行服务</a></li><li><a href="/ects/introduction/managerment.html" class="sidebar-link">管理任务</a></li><li><a href="/ects/introduction/more.html" class="sidebar-link">更多</a></li></ul> </div> <div class="page"> <div class="content"><h1 id="架构设计"><a href="#架构设计" aria-hidden="true" class="header-anchor">#</a> 架构设计</h1> <p><img src="/ects/architecture.png" alt="Architecture"></p> <h2 id="主节点"><a href="#主节点" aria-hidden="true" class="header-anchor">#</a> 主节点</h2> <p>主节点又称 Master 节点，在整个系统中起到了管理 API 和从节点的状态更新功能。</p> <p>当有新的节点注册到 ETCD 时，为了避免单个节点注册被多个 Master 节点重复更新数据库的情况。在实现上我们采用了基于 ETCD 的分布式锁，只有抢到锁的 Master 节点才能创建或更新节点信息。</p> <h2 id="从节点"><a href="#从节点" aria-hidden="true" class="header-anchor">#</a> 从节点</h2> <p>从节点也就是 Worker 节点，此类型的节点启动后便向 ETCD 注册自己的节点信息，然后从 ETCD 中获取需要在本机上运行的定时任务，并开始调度。</p> <p>当流水线执行完成后，无论成功或失败，都将执行结果保存到 MySQL 数据库中，便于用户排查问题。</p> <h2 id="服务注册"><a href="#服务注册" aria-hidden="true" class="header-anchor">#</a> 服务注册</h2> <p>所有节点会根据配置的节点 Key 前缀，向 ETCD 中 PUT 自己的节点信息，默认前缀是 <code>/ects/nodes</code> 你可以使用 <code>etcdctl</code> 命令，来查看已经注册的节点信息。</p> <div class="language-bash line-numbers-mode"><pre class="language-bash"><code><span class="token comment"># 使用 ETCD 3 API</span>
$ <span class="token builtin class-name">export</span> <span class="token assign-left variable">ETCDCTL_API</span><span class="token operator">=</span><span class="token number">3</span>

<span class="token comment"># 获取节点 Key 列表</span>
$ etcdctl get /ects/nodes --prefix --keys-only
/ects/nodes/7935d870-99b0-4d32-b799-dd1ec0c1795d

<span class="token comment"># 获取节点详情</span>
$ etcdctl get /ects/nodes/7935d870-99b0-4d32-b799-dd1ec0c1795d
/ects/nodes/7935d870-99b0-4d32-b799-dd1ec0c1795d
<span class="token punctuation">{</span><span class="token string">&quot;id&quot;</span><span class="token builtin class-name">:</span><span class="token string">&quot;7935d870-99b0-4d32-b799-dd1ec0c1795d&quot;</span>,<span class="token string">&quot;name&quot;</span><span class="token builtin class-name">:</span><span class="token string">&quot;George.local&quot;</span>,<span class="token string">&quot;host&quot;</span><span class="token builtin class-name">:</span><span class="token string">&quot;192.168.1.9&quot;</span>,<span class="token string">&quot;port&quot;</span>:9701,<span class="token string">&quot;mode&quot;</span><span class="token builtin class-name">:</span><span class="token string">&quot;master&quot;</span>,<span class="token string">&quot;status&quot;</span><span class="token builtin class-name">:</span><span class="token string">&quot;online&quot;</span>,<span class="token string">&quot;version&quot;</span><span class="token builtin class-name">:</span><span class="token string">&quot;0.3.0&quot;</span>,<span class="token string">&quot;description&quot;</span><span class="token builtin class-name">:</span><span class="token string">&quot;master node&quot;</span><span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br></div></div><p>解析结果如下：</p> <div class="language-json line-numbers-mode"><pre class="language-json"><code><span class="token punctuation">{</span>
    <span class="token property">&quot;id&quot;</span><span class="token operator">:</span> <span class="token string">&quot;7935d870-99b0-4d32-b799-dd1ec0c1795d&quot;</span><span class="token punctuation">,</span>
    <span class="token property">&quot;name&quot;</span><span class="token operator">:</span> <span class="token string">&quot;George.local&quot;</span><span class="token punctuation">,</span>
    <span class="token property">&quot;host&quot;</span><span class="token operator">:</span> <span class="token string">&quot;192.168.1.9&quot;</span><span class="token punctuation">,</span>
    <span class="token property">&quot;port&quot;</span><span class="token operator">:</span> <span class="token number">9701</span><span class="token punctuation">,</span>
    <span class="token property">&quot;mode&quot;</span><span class="token operator">:</span> <span class="token string">&quot;master&quot;</span><span class="token punctuation">,</span>
    <span class="token property">&quot;status&quot;</span><span class="token operator">:</span> <span class="token string">&quot;online&quot;</span><span class="token punctuation">,</span>
    <span class="token property">&quot;version&quot;</span><span class="token operator">:</span> <span class="token string">&quot;0.3.0&quot;</span><span class="token punctuation">,</span>
    <span class="token property">&quot;description&quot;</span><span class="token operator">:</span> <span class="token string">&quot;master node&quot;</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br></div></div><blockquote><p>节点 ID 为 UUID</p></blockquote> <h2 id="服务发现"><a href="#服务发现" aria-hidden="true" class="header-anchor">#</a> 服务发现</h2> <p>目前用到的服务发现，仅仅是 Master 检测 Worker 的变化。并更新数据库或发送通知给用户。</p> <h2 id="流水线"><a href="#流水线" aria-hidden="true" class="header-anchor">#</a> 流水线</h2> <p>因为考虑到有些任务需要关联起来，并且相互依赖，所以我们引入了流水线的模式。流水线可以关联多个任务，并排序任务执行顺序。</p> <p>以下是 PUT 到 ETCD 中的流水线数据结构</p> <div class="language-json line-numbers-mode"><pre class="language-json"><code><span class="token punctuation">{</span>
    <span class="token property">&quot;id&quot;</span><span class="token operator">:</span> <span class="token string">&quot;b6e54dc3-7e12-4029-b499-fb4603c72163&quot;</span><span class="token punctuation">,</span>
    <span class="token property">&quot;name&quot;</span><span class="token operator">:</span> <span class="token string">&quot;测试任务流水线&quot;</span><span class="token punctuation">,</span>
    <span class="token property">&quot;description&quot;</span><span class="token operator">:</span> <span class="token string">&quot;&quot;</span><span class="token punctuation">,</span>
    <span class="token property">&quot;spec&quot;</span><span class="token operator">:</span> <span class="token string">&quot;*/10 * * * * * *&quot;</span><span class="token punctuation">,</span>
    <span class="token property">&quot;status&quot;</span><span class="token operator">:</span> <span class="token number">0</span><span class="token punctuation">,</span>
    <span class="token property">&quot;finished&quot;</span><span class="token operator">:</span> <span class="token string">&quot;7a0a46fb-7f61-4b36-8005-a4da351f32fa&quot;</span><span class="token punctuation">,</span>
    <span class="token property">&quot;failed&quot;</span><span class="token operator">:</span> <span class="token string">&quot;7a0a46fb-7f61-4b36-8005-a4da351f32fa&quot;</span><span class="token punctuation">,</span>
    <span class="token property">&quot;overlap&quot;</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span>
    <span class="token property">&quot;created_at&quot;</span><span class="token operator">:</span> <span class="token string">&quot;2019-08-17 12:03:40&quot;</span><span class="token punctuation">,</span>
    <span class="token property">&quot;updated_at&quot;</span><span class="token operator">:</span> <span class="token string">&quot;2019-09-02 14:32:52&quot;</span><span class="token punctuation">,</span>
    <span class="token property">&quot;nodes&quot;</span><span class="token operator">:</span> <span class="token punctuation">[</span>
        <span class="token string">&quot;1d9988aa-4630-4230-a646-4a2f377d4530&quot;</span>
    <span class="token punctuation">]</span><span class="token punctuation">,</span>
    <span class="token property">&quot;steps&quot;</span><span class="token operator">:</span> <span class="token punctuation">[</span>
        <span class="token punctuation">{</span>
            <span class="token property">&quot;id&quot;</span><span class="token operator">:</span> <span class="token string">&quot;2bf41417-a2b6-43c8-8755-9a54c3fa654e&quot;</span><span class="token punctuation">,</span>
            <span class="token property">&quot;pipeline_id&quot;</span><span class="token operator">:</span> <span class="token string">&quot;b6e54dc3-7e12-4029-b499-fb4603c72163&quot;</span><span class="token punctuation">,</span>
            <span class="token property">&quot;task_id&quot;</span><span class="token operator">:</span> <span class="token string">&quot;4afe4ea7-67a3-4836-b8ef-3b4c356ff3fd&quot;</span><span class="token punctuation">,</span>
            <span class="token property">&quot;step&quot;</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span>
            <span class="token property">&quot;timeout&quot;</span><span class="token operator">:</span> <span class="token number">0</span><span class="token punctuation">,</span>
            <span class="token property">&quot;interval&quot;</span><span class="token operator">:</span> <span class="token number">0</span><span class="token punctuation">,</span>
            <span class="token property">&quot;retries&quot;</span><span class="token operator">:</span> <span class="token number">0</span><span class="token punctuation">,</span>
            <span class="token property">&quot;directory&quot;</span><span class="token operator">:</span> <span class="token string">&quot;&quot;</span><span class="token punctuation">,</span>
            <span class="token property">&quot;user&quot;</span><span class="token operator">:</span> <span class="token string">&quot;&quot;</span><span class="token punctuation">,</span>
            <span class="token property">&quot;environment&quot;</span><span class="token operator">:</span> <span class="token string">&quot;&quot;</span><span class="token punctuation">,</span>
            <span class="token property">&quot;dependence&quot;</span><span class="token operator">:</span> <span class="token string">&quot;strong&quot;</span><span class="token punctuation">,</span>
            <span class="token property">&quot;created_at&quot;</span><span class="token operator">:</span> <span class="token string">&quot;2019-08-17 12:05:26&quot;</span><span class="token punctuation">,</span>
            <span class="token property">&quot;updated_at&quot;</span><span class="token operator">:</span> <span class="token string">&quot;2019-08-17 12:05:26&quot;</span><span class="token punctuation">,</span>
            <span class="token property">&quot;task&quot;</span><span class="token operator">:</span> <span class="token punctuation">{</span>
                <span class="token property">&quot;id&quot;</span><span class="token operator">:</span> <span class="token string">&quot;4afe4ea7-67a3-4836-b8ef-3b4c356ff3fd&quot;</span><span class="token punctuation">,</span>
                <span class="token property">&quot;name&quot;</span><span class="token operator">:</span> <span class="token string">&quot;测试任务&quot;</span><span class="token punctuation">,</span>
                <span class="token property">&quot;mode&quot;</span><span class="token operator">:</span> <span class="token string">&quot;shell&quot;</span><span class="token punctuation">,</span>
                <span class="token property">&quot;url&quot;</span><span class="token operator">:</span> <span class="token string">&quot;&quot;</span><span class="token punctuation">,</span>
                <span class="token property">&quot;method&quot;</span><span class="token operator">:</span> <span class="token string">&quot;post&quot;</span><span class="token punctuation">,</span>
                <span class="token property">&quot;content&quot;</span><span class="token operator">:</span> <span class="token string">&quot;sleep 3 &amp;&amp; echo \&quot;done\&quot;&quot;</span><span class="token punctuation">,</span>
                <span class="token property">&quot;description&quot;</span><span class="token operator">:</span> <span class="token string">&quot;测试任务&quot;</span><span class="token punctuation">,</span>
                <span class="token property">&quot;created_at&quot;</span><span class="token operator">:</span> <span class="token string">&quot;2019-08-17 12:02:53&quot;</span><span class="token punctuation">,</span>
                <span class="token property">&quot;updated_at&quot;</span><span class="token operator">:</span> <span class="token string">&quot;2019-08-28 14:13:06&quot;</span>
            <span class="token punctuation">}</span>
        <span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{</span>
            <span class="token property">&quot;id&quot;</span><span class="token operator">:</span> <span class="token string">&quot;4379cc1a-ddbf-4940-8ce2-9add3e276abb&quot;</span><span class="token punctuation">,</span>
            <span class="token property">&quot;pipeline_id&quot;</span><span class="token operator">:</span> <span class="token string">&quot;b6e54dc3-7e12-4029-b499-fb4603c72163&quot;</span><span class="token punctuation">,</span>
            <span class="token property">&quot;task_id&quot;</span><span class="token operator">:</span> <span class="token string">&quot;d2e3f791-339b-41c4-8b37-10c3bbd9aa34&quot;</span><span class="token punctuation">,</span>
            <span class="token property">&quot;step&quot;</span><span class="token operator">:</span> <span class="token number">2</span><span class="token punctuation">,</span>
            <span class="token property">&quot;timeout&quot;</span><span class="token operator">:</span> <span class="token number">0</span><span class="token punctuation">,</span>
            <span class="token property">&quot;interval&quot;</span><span class="token operator">:</span> <span class="token number">0</span><span class="token punctuation">,</span>
            <span class="token property">&quot;retries&quot;</span><span class="token operator">:</span> <span class="token number">0</span><span class="token punctuation">,</span>
            <span class="token property">&quot;directory&quot;</span><span class="token operator">:</span> <span class="token string">&quot;&quot;</span><span class="token punctuation">,</span>
            <span class="token property">&quot;user&quot;</span><span class="token operator">:</span> <span class="token string">&quot;&quot;</span><span class="token punctuation">,</span>
            <span class="token property">&quot;environment&quot;</span><span class="token operator">:</span> <span class="token string">&quot;&quot;</span><span class="token punctuation">,</span>
            <span class="token property">&quot;dependence&quot;</span><span class="token operator">:</span> <span class="token string">&quot;strong&quot;</span><span class="token punctuation">,</span>
            <span class="token property">&quot;created_at&quot;</span><span class="token operator">:</span> <span class="token string">&quot;2019-08-31 15:09:59&quot;</span><span class="token punctuation">,</span>
            <span class="token property">&quot;updated_at&quot;</span><span class="token operator">:</span> <span class="token string">&quot;2019-08-31 15:09:59&quot;</span><span class="token punctuation">,</span>
            <span class="token property">&quot;task&quot;</span><span class="token operator">:</span> <span class="token punctuation">{</span>
                <span class="token property">&quot;id&quot;</span><span class="token operator">:</span> <span class="token string">&quot;d2e3f791-339b-41c4-8b37-10c3bbd9aa34&quot;</span><span class="token punctuation">,</span>
                <span class="token property">&quot;name&quot;</span><span class="token operator">:</span> <span class="token string">&quot;查看目录&quot;</span><span class="token punctuation">,</span>
                <span class="token property">&quot;mode&quot;</span><span class="token operator">:</span> <span class="token string">&quot;shell&quot;</span><span class="token punctuation">,</span>
                <span class="token property">&quot;url&quot;</span><span class="token operator">:</span> <span class="token string">&quot;&quot;</span><span class="token punctuation">,</span>
                <span class="token property">&quot;method&quot;</span><span class="token operator">:</span> <span class="token string">&quot;post&quot;</span><span class="token punctuation">,</span>
                <span class="token property">&quot;content&quot;</span><span class="token operator">:</span> <span class="token string">&quot;sleep 3 &amp;&amp; ls -la&quot;</span><span class="token punctuation">,</span>
                <span class="token property">&quot;description&quot;</span><span class="token operator">:</span> <span class="token string">&quot;查看目录结构&quot;</span><span class="token punctuation">,</span>
                <span class="token property">&quot;created_at&quot;</span><span class="token operator">:</span> <span class="token string">&quot;2019-08-31 15:09:42&quot;</span><span class="token punctuation">,</span>
                <span class="token property">&quot;updated_at&quot;</span><span class="token operator">:</span> <span class="token string">&quot;2019-08-31 15:09:42&quot;</span>
            <span class="token punctuation">}</span>
        <span class="token punctuation">}</span>
    <span class="token punctuation">]</span><span class="token punctuation">,</span>
    <span class="token property">&quot;finished_task&quot;</span><span class="token operator">:</span> <span class="token punctuation">{</span>
        <span class="token property">&quot;id&quot;</span><span class="token operator">:</span> <span class="token string">&quot;7a0a46fb-7f61-4b36-8005-a4da351f32fa&quot;</span><span class="token punctuation">,</span>
        <span class="token property">&quot;name&quot;</span><span class="token operator">:</span> <span class="token string">&quot;绑定IP&quot;</span><span class="token punctuation">,</span>
        <span class="token property">&quot;mode&quot;</span><span class="token operator">:</span> <span class="token string">&quot;shell&quot;</span><span class="token punctuation">,</span>
        <span class="token property">&quot;url&quot;</span><span class="token operator">:</span> <span class="token string">&quot;&quot;</span><span class="token punctuation">,</span>
        <span class="token property">&quot;method&quot;</span><span class="token operator">:</span> <span class="token string">&quot;post&quot;</span><span class="token punctuation">,</span>
        <span class="token property">&quot;content&quot;</span><span class="token operator">:</span> <span class="token string">&quot;bind aliyun dns&quot;</span><span class="token punctuation">,</span>
        <span class="token property">&quot;description&quot;</span><span class="token operator">:</span> <span class="token string">&quot;绑定IP到DNS&quot;</span><span class="token punctuation">,</span>
        <span class="token property">&quot;created_at&quot;</span><span class="token operator">:</span> <span class="token string">&quot;2019-08-29 17:31:42&quot;</span><span class="token punctuation">,</span>
        <span class="token property">&quot;updated_at&quot;</span><span class="token operator">:</span> <span class="token string">&quot;2019-08-29 17:31:42&quot;</span>
    <span class="token punctuation">}</span><span class="token punctuation">,</span>
    <span class="token property">&quot;failed_task&quot;</span><span class="token operator">:</span> <span class="token punctuation">{</span>
        <span class="token property">&quot;id&quot;</span><span class="token operator">:</span> <span class="token string">&quot;7a0a46fb-7f61-4b36-8005-a4da351f32fa&quot;</span><span class="token punctuation">,</span>
        <span class="token property">&quot;name&quot;</span><span class="token operator">:</span> <span class="token string">&quot;绑定IP&quot;</span><span class="token punctuation">,</span>
        <span class="token property">&quot;mode&quot;</span><span class="token operator">:</span> <span class="token string">&quot;shell&quot;</span><span class="token punctuation">,</span>
        <span class="token property">&quot;url&quot;</span><span class="token operator">:</span> <span class="token string">&quot;&quot;</span><span class="token punctuation">,</span>
        <span class="token property">&quot;method&quot;</span><span class="token operator">:</span> <span class="token string">&quot;post&quot;</span><span class="token punctuation">,</span>
        <span class="token property">&quot;content&quot;</span><span class="token operator">:</span> <span class="token string">&quot;bind aliyun dns&quot;</span><span class="token punctuation">,</span>
        <span class="token property">&quot;description&quot;</span><span class="token operator">:</span> <span class="token string">&quot;绑定IP到DNS&quot;</span><span class="token punctuation">,</span>
        <span class="token property">&quot;created_at&quot;</span><span class="token operator">:</span> <span class="token string">&quot;2019-08-29 17:31:42&quot;</span><span class="token punctuation">,</span>
        <span class="token property">&quot;updated_at&quot;</span><span class="token operator">:</span> <span class="token string">&quot;2019-08-29 17:31:42&quot;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br><span class="line-number">31</span><br><span class="line-number">32</span><br><span class="line-number">33</span><br><span class="line-number">34</span><br><span class="line-number">35</span><br><span class="line-number">36</span><br><span class="line-number">37</span><br><span class="line-number">38</span><br><span class="line-number">39</span><br><span class="line-number">40</span><br><span class="line-number">41</span><br><span class="line-number">42</span><br><span class="line-number">43</span><br><span class="line-number">44</span><br><span class="line-number">45</span><br><span class="line-number">46</span><br><span class="line-number">47</span><br><span class="line-number">48</span><br><span class="line-number">49</span><br><span class="line-number">50</span><br><span class="line-number">51</span><br><span class="line-number">52</span><br><span class="line-number">53</span><br><span class="line-number">54</span><br><span class="line-number">55</span><br><span class="line-number">56</span><br><span class="line-number">57</span><br><span class="line-number">58</span><br><span class="line-number">59</span><br><span class="line-number">60</span><br><span class="line-number">61</span><br><span class="line-number">62</span><br><span class="line-number">63</span><br><span class="line-number">64</span><br><span class="line-number">65</span><br><span class="line-number">66</span><br><span class="line-number">67</span><br><span class="line-number">68</span><br><span class="line-number">69</span><br><span class="line-number">70</span><br><span class="line-number">71</span><br><span class="line-number">72</span><br><span class="line-number">73</span><br><span class="line-number">74</span><br><span class="line-number">75</span><br><span class="line-number">76</span><br><span class="line-number">77</span><br><span class="line-number">78</span><br><span class="line-number">79</span><br><span class="line-number">80</span><br><span class="line-number">81</span><br><span class="line-number">82</span><br><span class="line-number">83</span><br><span class="line-number">84</span><br><span class="line-number">85</span><br><span class="line-number">86</span><br><span class="line-number">87</span><br><span class="line-number">88</span><br><span class="line-number">89</span><br><span class="line-number">90</span><br><span class="line-number">91</span><br></div></div><ul><li>nodes 对应的是流水线需要在那些 Worker 节点上运行，节点在监听到 PUT 事件以后，根据 <code>nodes</code> 里的节点 ID 判断自己是否需要将流水线加入调度列表。</li> <li>steps 流水线执行步骤，按照顺序逐个执行，如果中途发生异常则终止整个流水线，并记录日志。</li> <li>finished_task 当流水线成功后触发的任务。</li> <li>failed_task 当流水线失败后触发的任务。</li></ul> <h2 id="任务"><a href="#任务" aria-hidden="true" class="header-anchor">#</a> 任务</h2> <p>单个任务无法直接在 Worker 上进行调度，Worker 调度的最小单位是流水线。</p> <h2 id="关联关系"><a href="#关联关系" aria-hidden="true" class="header-anchor">#</a> 关联关系</h2> <p><img src="/ects/pipelines_relations.png" alt="Relations"></p> <p>如果想在某台 Worker 节点上运行一个定时任务，你必须将任务添加到流水线的执行步骤中，紧接着将流水线绑定到对应的节点上，这样实现的目的是尽可能的避免跨主机的任务重复定义的问题。</p> <p>上图中，<code>task2</code> 可以在 <code>pipeline1</code> 中被调度执行，也可以在 <code>pipeline2</code> 中别调度执行，而 <code>pipeline1</code> 又绑定到了 <code>worker1</code>、<code>worker2</code>、<code>worker3</code> 节点上，也就是说三个节点上都会调度执行 <code>pipeline1</code> 下的任务。</p></div> <div class="page-edit"><!----> <!----></div> <div class="page-nav"><p class="inner"><!----> <span class="next"><a href="/ects/introduction/dependencies.html">
          环境依赖
        </a>
        →
      </span></p></div> </div> <!----></div></div>
    <script src="/ects/assets/js/app.dc03944a.js" defer></script><script src="/ects/assets/js/6.fe2e5ce2.js" defer></script>
  </body>
</html>
